package com.xxx.springboot.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * 初始化敏感词库，将敏感词加入到HashMap中，构建DFA算法模型
 * 参考：https://blog.csdn.net/chenssy/article/details/26961957
 */
public class SensitiveWordInit {
	
	private String ENCODING = "UTF-8"; // 敏感词库文件字符编码
	
	@SuppressWarnings("rawtypes")
	public HashMap sensitiveWordMap;  // 敏感词库
	
	public SensitiveWordInit(){
		super();
	}
	
	/**
	 * 初始化敏感词库
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public Map init(){
		try {
			// 读取敏感词库
			Set<String> keyWordSet = this.readSensitiveWordFile();
			
			// 将敏感词库加入到HashMap中
			addSensitiveWordToHashMap(keyWordSet);
			// spring获取application，然后application.setAttribute("sensitiveWordMap", sensitiveWordMap);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return sensitiveWordMap;
	}

	/**
	 * 读取敏感词库，将敏感词放入HashSet中，构建一个DFA算法模型
	 * @param keyWordSet
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	private void addSensitiveWordToHashMap(Set<String> keyWordSet) {
		sensitiveWordMap = new HashMap(keyWordSet.size());  // 初始化敏感词容器，减少扩容操作
		String key = null;  
		Map nowMap = null;
		Map<String, String> newWorMap = null;
		Iterator<String> iterator = keyWordSet.iterator();
		while(iterator.hasNext()){
			key = iterator.next();  // 关键字
			nowMap = sensitiveWordMap;
			for(int i=0; i<key.length(); i++){
				char keyChar = key.charAt(i);  // 转换成char型
				Object wordMap = nowMap.get(keyChar);  // 获取
				if(wordMap != null){ // 如果存在该key，直接赋值
					nowMap = (Map) wordMap;
				} else{ // 不存在则构建一个map，同时将isEnd设置为0，因为他不是最后一个
					newWorMap = new HashMap<String,String>();
					newWorMap.put("isEnd", "0");  // 不是最后一个
					nowMap.put(keyChar, newWorMap);
					nowMap = newWorMap;
				}
				
				if(i==key.length() - 1){
					nowMap.put("isEnd", "1"); // 最后一个
				}
			}
		}
	}

	/**
	 * 读取敏感词库中的内容，将内容添加到set集合中（这里采用读取文件的方式，也可以采用读取数据库的方式）
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("resource")
	private Set<String> readSensitiveWordFile() throws Exception{
		Set<String> set = null; // 读取结果
		File file = new File("D:\\SensitiveWord.txt");  // 读取文件
		InputStreamReader read = new InputStreamReader(new FileInputStream(file), ENCODING);
		try {
			if(file.isFile() && file.exists()) { // 文件流是否存在
				set = new HashSet<String>();
				BufferedReader bufferedReader = new BufferedReader(read);
				String txt = null;
				while((txt = bufferedReader.readLine()) != null){ // 读取文件，将文件内容放入到set中
					set.add(txt);
			    }
			} else { //不存在抛出异常信息
				throw new Exception("敏感词库文件【SensitiveWord.txt】不存在");
			}
		} catch (Exception e) {
			throw e;
		} finally {
			read.close(); // 关闭文件流
		}
		return set;
	}
}
